package com.dylan.历史.多线程.并发编程的艺术;

import com.dylan.历史.util.LogUtil;

import java.util.Arrays;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.Future;
import java.util.concurrent.RecursiveTask;

/**
 * Created by Dylan on 2018/9/20.
 */
public class ForkJoinTest {

    public static void main(String[] args) {
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        // 生成一个任务
        CountTask task = new CountTask(1, 2, 3, 4, 5, 6, 7, 8, 9);
        // 执行一个任务
        Future<Integer> result = forkJoinPool.submit(task);
        try {
            LogUtil.info("结果：" + result.get());
        } catch (InterruptedException | ExecutionException e) {
            e.printStackTrace();
        }
    }


    static class CountTask extends RecursiveTask<Integer> {
        private static final int THRESHOLD = 2; // 阀值

        private int[] num;

        CountTask(int... num) {
            this.num = num;
        }

        @Override
        protected Integer compute() {
            if (num.length <= THRESHOLD) {
                LogUtil.info("我在计算");
                int sum = 0;
                for (int aNum : num) {
                    sum += aNum;
                }
                return sum;
            } else {
                // 如果任务大于阀值，就分裂成两个子任务计算
                int middle = num.length / 2;
                CountTask leftTask = new CountTask(Arrays.copyOfRange(num, 0, middle));
                CountTask rightTask = new CountTask(Arrays.copyOfRange(num, middle, num.length));

                // 执行子任务
                leftTask.fork();
                rightTask.fork();

                // 等待子任务执行完成，并得到结果
                int leftResult = leftTask.join();
                int rightResult = rightTask.join();

                // 合并子任务结果
                return leftResult + rightResult;
            }
        }
    }
}
